package com.hardson.toolkit.swing.datepicker;

import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.text.JTextComponent;

import com.hardson.toolkit.swing.ScreenSize;
import com.hardson.toolkit.util.DateUtil;

public class DatePickerDialog extends JDialog implements IPickerCallBack {

	/**
	 *
	 */
	private static final long serialVersionUID = 1L;

	public static int PICKERTYPE_DATEANDTIME = DatePickerPanel.PICKERTYPE_DATEANDTIME;// 显示日期和时间

	public static int PICKERTYPE_DATEONLY = DatePickerPanel.PICKERTYPE_DATEONLY;// 只显示日期

	public static int PICKERTYPE_TIMEONLY = DatePickerPanel.PICKERTYPE_TIMEONLY;// 只显示时间

	public static int ACTIONTYPE_CONFIRM = DatePickerPanel.ACTIONTYPE_CONFIRM;// 确认

	public static int ACTIONTYPE_RESET = DatePickerPanel.ACTIONTYPE_RESET;// 重置

	public static int ACTIONTYPE_CANCEL = DatePickerPanel.ACTIONTYPE_CANCEL;// 取消

	private Calendar selectedDate = Calendar.getInstance();

	private DatePickerPanel pnlPicker;

	private int pickerType = PICKERTYPE_DATEANDTIME;

	Image bgImg = null;

	Image headImg = null;

	private JTextComponent textComp = null;

	private String dateFormat = "";

	// private boolean parentModal = false;

	public DatePickerDialog(final Frame owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		this.initComponent();
	}

	public DatePickerDialog(final Frame owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType, final String pattern, final String dateString) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		if (dateString != null && dateString.length() > 0) {
			try {
				SimpleDateFormat sdf = new SimpleDateFormat(pattern);
				this.selectedDate.setTimeInMillis(sdf.parse(dateString).getTime());
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		this.initComponent();
	}

	public DatePickerDialog(final Frame owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType, final Date date) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		if (date != null) {
			this.selectedDate.setTime(date);
		}
		this.initComponent();
	}

	public DatePickerDialog(final Dialog owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		this.initComponent();
	}

	public DatePickerDialog(final Dialog owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType, final String pattern, final String dateString) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		if (dateString != null && dateString.length() > 0) {
			try {
				SimpleDateFormat sdf = new SimpleDateFormat(pattern);
				this.selectedDate.setTimeInMillis(sdf.parse(dateString).getTime());
			} catch (ParseException e) {
				System.err.println(e.getMessage());
			}
		}

		this.initComponent();
	}

	public DatePickerDialog(final Dialog owner, final Image headImg, final Image bgImg, final String title,
			final boolean modal, final int pickerType, final Date date) {
		super(owner, title, modal);
		this.pickerType = pickerType;
		this.bgImg = bgImg;
		this.headImg = headImg;
		if (date != null) {
			this.selectedDate.setTime(date);
		}
		this.initComponent();
	}

	private void initComponent() {
		this.setUndecorated(true);
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		if (this.pickerType == DatePickerPanel.PICKERTYPE_TIMEONLY) {
			this.setPreferredSize(new Dimension(149, 74));
		} else {
			this.setPreferredSize(new Dimension(320, 320));
		}
		this.pnlPicker = new DatePickerPanel(this, this.headImg, this.bgImg, this.selectedDate, this.pickerType);
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(this.pnlPicker, BorderLayout.CENTER);
		//this.setFont(this.textComp.getFont());
		this.pack();
		Window owner = this.getOwner();
		if (owner instanceof IAutoHide) {
			IAutoHide d = ((IAutoHide) owner);
			d.setWindowListenerActive(false);
		}
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowDeactivated(final WindowEvent e) {
				DatePickerDialog.this.dispose();
			}
		});
	}

	@Override
	public void dispose() {
		Window owner = this.getOwner();
		if (owner instanceof IAutoHide) {
			IAutoHide d = ((IAutoHide) owner);
			d.setWindowListenerActive(true);
			d.requestFocus();
		}
		super.dispose();
	}

	/**
	 * 添加ESCAPE监听，按下ESCAPE键后退出
	 */
	@Override
	protected JRootPane createRootPane() {
		KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
		JRootPane rootPane = super.createRootPane();
		rootPane.registerKeyboardAction(new ActionListener() {
			@Override
			public void actionPerformed(final ActionEvent e) {
				DatePickerDialog.this.dispose();
			}
		}, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
		return rootPane;
	}
	/*
	 * public static void main(final String args[]) { final JFrame f = new
	 * JFrame(); JButton btn = new JButton("选择日期"); f.getContentPane().add(btn);
	 * btn.addActionListener(new ActionListener() {
	 *
	 * public void actionPerformed(final ActionEvent e) { new
	 * DatePickDialog(f,null,null, "日期选择控件",
	 * true,PICKERTYPE_DATEANDTIME).setVisible(true); }
	 *
	 * });
	 *
	 * f.setSize(300, 300); f.setVisible(true);
	 * f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
	 */

	/**
	 * 日历面板回调处理接口
	 *
	 * @param action 动作类型：确定 ACTIONTYPE_CONFIRM,重置 ACTIONTYPE_RESET,取消
	 *               ACTIONTYPE_CANCEL
	 */
	@Override
	public void recall(final int action) {
		if (action == DatePickerDialog.ACTIONTYPE_CONFIRM) {
			Calendar c = this.pnlPicker.getCalendar();
			String newDate = DateUtil.dateToStr(c.getTimeInMillis(), this.dateFormat);
			this.textComp.setText(newDate);
		} else if (action == DatePickerDialog.ACTIONTYPE_RESET) {
			this.textComp.setText("");
		}
		this.dispose();
	}

	public static void pickDate(final Window owner, final JTextComponent textComp, final int pickerType,
			final String dateFormat) {

		String execTimeStr = textComp.getText().trim();
		DatePickerDialog d = null;
		if (owner instanceof Dialog) {
			d = new DatePickerDialog((Dialog) owner, null, null, "", false, pickerType, dateFormat, execTimeStr);
		} else if (owner instanceof Frame) {
			d = new DatePickerDialog((Frame) owner, null, null, "", false, pickerType, dateFormat, execTimeStr);
		}

		initDialog(d, textComp, dateFormat);
	}

	private static void initDialog(final DatePickerDialog d, final JTextComponent textComp, final String dateFormat) {
		d.textComp = textComp;
		d.dateFormat = dateFormat;
		Point p = textComp.getLocationOnScreen();
		p.y = p.y + textComp.getHeight();
		if (p.y + d.getHeight() > ScreenSize.getScreenHeight()) {
			p.y = p.y - textComp.getHeight() - d.getHeight();
		}
		d.setLocation(p);
		d.setVisible(true);
	}

	@Override
	public void setFont(final Font font) {
		super.setFont(font);
		this.pnlPicker.setFont(font);
	}
}